using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Windows.Media;
using System.Diagnostics;

namespace KeyboardImageViewer
{
	public static class Utilities
	{
        private const string RandomChars = "0123456789abcdefghijklmnopqrstuvwxyz";

        private static Brush color4 = new SolidColorBrush(Color.FromArgb(0xff, 0xb9, 0xff, 0x9b));
        private static Brush color5 = new SolidColorBrush(Color.FromArgb(0xff, 0x43, 0xe0, 0x00));

        public const int CurrentDatabaseVersion = 6;
        public const string CurrentVersion = "1.4.5";
        public const string UpdateInfoUrl = "http://engy.us/kiv/latest.xml";
        public const string AppDataFolderName = "Keyboard Image Viewer";

        public static FileInfoNameComparer FileInfoNameComparer = new FileInfoNameComparer();

        public static string UpdatesFolder
        {
            get
            {
                string updatesFolder;

                string appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataFolderName);
                updatesFolder = Path.Combine(appDataFolder, "Updates");

                if (!Directory.Exists(updatesFolder))
                {
                    Directory.CreateDirectory(updatesFolder);
                }

                return updatesFolder;
            }
        }

        public static int CurrentProcessInstances
        {
            get
            {
                Process[] processList = Process.GetProcessesByName("KeyboardImageViewer");
                return processList.Length;
            }
        }

        public static int CompareVersions(string versionA, string versionB)
        {
            string[] stringPartsA = versionA.Split('.');
            string[] stringPartsB = versionB.Split('.');

            int[] intPartsA = new int[stringPartsA.Length];
            int[] intPartsB = new int[stringPartsB.Length];

            for (int i = 0; i < intPartsA.Length; i++)
            {
                intPartsA[i] = int.Parse(stringPartsA[i]);
            }

            for (int i = 0; i < intPartsB.Length; i++)
            {
                intPartsB[i] = int.Parse(stringPartsB[i]);
            }

            int compareLength = Math.Min(intPartsA.Length, intPartsB.Length);

            for (int i = 0; i < compareLength; i++)
            {
                if (intPartsA[i] > intPartsB[i])
                {
                    return 1;
                }
                else if (intPartsA[i] < intPartsB[i])
                {
                    return -1;
                }
            }

            if (intPartsA.Length > intPartsB.Length)
            {
                for (int i = compareLength; i < intPartsA.Length; i++)
                {
                    if (intPartsA[i] > 0)
                    {
                        return 1;
                    }
                }
            }

            if (intPartsA.Length < intPartsB.Length)
            {
                for (int i = compareLength; i < intPartsB.Length; i++)
                {
                    if (intPartsB[i] > 0)
                    {
                        return 1;
                    }
                }
            }

            return 0;
        }

        public static Brush GetColorFromRating(int rating)
		{
			switch (rating)
			{
				case 1:
					return Brushes.Red;
				case 2:
					return Brushes.Orange;
				case 3:
					return Brushes.Yellow;
				case 4:
					return color4;
				case 5:
					return color5;
				default:
					return Brushes.Purple; // To show there was an error
			}
		}

		public static string GetHash(string path)
		{
			MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

			byte[] hash;
			try
			{
				FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
				hash = md5.ComputeHash(stream);
				stream.Close();
			}
			catch (UnauthorizedAccessException)
			{
				return "";
			}

			StringBuilder sb = new StringBuilder();

			foreach (byte b in hash)
			{
				sb.Append(b.ToString("x2"));
			}

			return sb.ToString();
		}

        public static string ConvertBytesToString(long bytes)
        {
            if (bytes < 1024)
            {
                return bytes.ToString() + " bytes";
            }

            if (bytes < 1048576)
            {
                double kilobytes = ((double)bytes) / 1024;

                return kilobytes.ToString(GetFormatForFilesize(kilobytes)) + " KB";
            }

            double megabytes = ((double)bytes) / 1048576;

            return megabytes.ToString(GetFormatForFilesize(megabytes)) + " MB";
        }

        public static List<string> ListFromPipeList(string pipeList)
        {
            if (pipeList == null || pipeList.Length < 2)
            {
                return new List<string>();
            }

            string[] parts = pipeList.Substring(1, pipeList.Length - 2).Split(new char[] { '|' });
            return new List<string>(parts);
        }

        public static string PipeListFromList(IEnumerable<string> list)
        {
            int tagsAdded = 0;

            StringBuilder builder = new StringBuilder();

            foreach (string item in list)
            {
                if (!item.Contains(",") && !item.Contains("|"))
                {
                    builder.Append("|");
                    builder.Append(item.Trim());

                    tagsAdded++;
                }
            }

            if (tagsAdded > 0)
            {
                builder.Append("|");
            }

            return builder.ToString();
        }

        public static string CommaListFromList(List<string> list)
        {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < list.Count; i++)
            {
                builder.Append(list[i]);

                if (i != list.Count - 1)
                {
                    builder.Append(", ");
                }
            }

            return builder.ToString();
        }

        public static string CalculateDependentTags(List<string> tags, List<KeyValuePair<string, string>> dependencyList)
        {
            var dependentTags = new List<string>();

            foreach (KeyValuePair<string, string> dependency in dependencyList)
            {
                if (tags.Contains(dependency.Key))
                {
                    dependentTags.Add(dependency.Value);
                }
            }

            return PipeListFromList(dependentTags);
        }

        public static string RemoveTrailingBackslash(string text)
        {
            if (text.Length < 1)
            {
                return text;
            }

            if (text[text.Length - 1] == '\\')
            {
                return text.Substring(0, text.Length - 1);
            }

            return text;
        }

        public static string GetRandomString(int length)
        {
            StringBuilder randomStringBuilder = new StringBuilder();
            Random random = new Random();

            for (int i = 0; i < length; i++)
            {
                randomStringBuilder.Append(RandomChars[random.Next(RandomChars.Length)]);
            }

            return randomStringBuilder.ToString();
        }

        private static string GetFormatForFilesize(double size)
        {
            int digits = 0;
            double num = size;

            while (num > 1.0)
            {
                num /= 10;
                digits++;
            }

            int decimalPlaces = Math.Min(2, 3 - digits);

            return "F" + decimalPlaces;
        }
	}
}
